<template>
  <div class="srtx_bg">
    <div class="srtx_imags">
      <div class="srtx_name">生日快乐</div>
      <div class="srtx_nametwo">祝你财源滚滚</div>
    </div>
    <div class="leift_lp"></div>
    <div class="right_lp"></div>
    <canvas ref="confettiCanvas" class="confetti-canvas"></canvas>

    <!-- <img src="../../assets//iconIndex/srtx.png" alt=""> -->
  </div>
</template>

<script>
export default {
  name: "srtx",
  mounted() {
    this.initConfetti();
  },
  beforeDestroy() {
    this.confetti && this.confetti.reset();
  },
  methods: {
    initConfetti() {
      const canvas = this.$refs.confettiCanvas;
      const ctx = canvas.getContext("2d");

      // 配置参数
      const defaults = {
        particleCount: 50,
        angle: 90,
        spread: 45,
        startVelocity: 45,
        decay: 0.9,
        gravity: 1,
        drift: 0,
        ticks: 200,
        x: 0.5,
        y: 0.5,
        shapes: ["square", "circle"],
        colors: [
          "#26ccff",
          "#a25afd",
          "#ff5e7e",
          "#88ff5a",
          "#fcff42",
          "#ffa62d",
          "#ff36ff",
        ],
        zIndex: 100,
        disableForReducedMotion: false,
        scalar: 1,
      };

      // 工具函数
      function mergeOptions(options) {
        return { ...defaults, ...options };
      }

      function hexToRgb(hex) {
        const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
        hex = hex.replace(
          shorthandRegex,
          (m, r, g, b) => r + r + g + g + b + b
        );
        const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
        return result
          ? {
              r: parseInt(result[1], 16),
              g: parseInt(result[2], 16),
              b: parseInt(result[3], 16),
            }
          : null;
      }

      function randomInRange(min, max) {
        return Math.random() * (max - min) + min;
      }

      // 粒子类
      class Particle {
        constructor(x, y, options) {
          this.x = x;
          this.y = y;
          this.wobble = randomInRange(0, 10);
          this.wobbleSpeed = randomInRange(0.05, 0.11);
          this.velocity = randomInRange(
            options.startVelocity * 0.5,
            options.startVelocity
          );

          const angle = (options.angle * Math.PI) / 180;
          const spread = (options.spread * Math.PI) / 180;
          this.angle2D = -angle + (Math.random() * spread - spread / 2);

          this.tiltAngle = randomInRange(0.25, 0.75) * Math.PI;
          this.color = hexToRgb(
            options.colors[Math.floor(Math.random() * options.colors.length)]
          );
          this.shape =
            options.shapes[Math.floor(Math.random() * options.shapes.length)];
          this.tick = 0;
          this.totalTicks = options.ticks;
          this.decay = options.decay;
          this.drift = options.drift;
          this.random = Math.random() + 2;
          this.tiltSin = 0;
          this.tiltCos = 0;
          this.wobbleX = 0;
          this.wobbleY = 0;
          this.gravity = options.gravity * 3;
          this.ovalScalar = 0.6;
          this.scalar = options.scalar;
        }

        update() {
          this.x += Math.cos(this.angle2D) * this.velocity + this.drift;
          this.y += Math.sin(this.angle2D) * this.velocity + this.gravity;
          this.wobble += this.wobbleSpeed;
          this.velocity *= this.decay;
          this.tiltAngle += 0.1;
          this.tiltSin = Math.sin(this.tiltAngle);
          this.tiltCos = Math.cos(this.tiltAngle);
          this.wobbleX = this.x + 10 * this.scalar * Math.cos(this.wobble);
          this.wobbleY = this.y + 10 * this.scalar * Math.sin(this.wobble);
          this.tick++;
        }

        draw(ctx) {
          const progress = this.tick / this.totalTicks;
          ctx.fillStyle = `rgba(${this.color.r}, ${this.color.g}, ${
            this.color.b
          }, ${1 - progress})`;

          const x1 = this.x + this.random * this.tiltCos;
          const y1 = this.y + this.random * this.tiltSin;
          const x2 = this.wobbleX + this.random * this.tiltCos;
          const y2 = this.wobbleY + this.random * this.tiltSin;

          ctx.beginPath();
          if (this.shape === "circle") {
            if (ctx.ellipse) {
              ctx.ellipse(
                this.x,
                this.y,
                Math.abs(x2 - x1) * this.ovalScalar,
                Math.abs(y2 - y1) * this.ovalScalar,
                (Math.PI / 10) * this.wobble,
                0,
                2 * Math.PI
              );
            } else {
              // 降级处理
              ctx.save();
              ctx.translate(this.x, this.y);
              ctx.rotate((Math.PI / 10) * this.wobble);
              ctx.scale(
                Math.abs(x2 - x1) * this.ovalScalar,
                Math.abs(y2 - y1) * this.ovalScalar
              );
              ctx.arc(0, 0, 1, 0, 2 * Math.PI);
              ctx.restore();
            }
          } else {
            // 方形/其他形状
            ctx.moveTo(Math.floor(this.x), Math.floor(this.y));
            ctx.lineTo(Math.floor(this.wobbleX), Math.floor(y1));
            ctx.lineTo(Math.floor(x2), Math.floor(y2));
            ctx.lineTo(Math.floor(x1), Math.floor(this.wobbleY));
          }
          ctx.closePath();
          ctx.fill();
        }
      }

      // 主类
      class Confetti {
        constructor(canvas) {
          this.canvas = canvas;
          this.ctx = canvas.getContext("2d");
          this.particles = [];
          this.animationId = null;
          this.resize();
          window.addEventListener("resize", this.resize.bind(this));
        }

        resize() {
          this.canvas.width = window.innerWidth;
          this.canvas.height = window.innerHeight;
        }

        createParticles(options) {
          const opts = mergeOptions(options);
          const x = opts.x * this.canvas.width;
          const y = opts.y * this.canvas.height;

          for (let i = 0; i < opts.particleCount; i++) {
            this.particles.push(new Particle(x, y, opts));
          }
        }

        animate() {
          this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

          this.particles = this.particles.filter((p) => {
            p.update();
            p.draw(this.ctx);
            return p.tick < p.totalTicks;
          });

          if (this.particles.length > 0) {
            this.animationId = requestAnimationFrame(this.animate.bind(this));
          } else {
            this.animationId = null;
          }
        }

        fire(options) {
          this.createParticles(options);
          if (!this.animationId) {
            this.animate();
          }
        }

        reset() {
          cancelAnimationFrame(this.animationId);
          this.animationId = null;
          this.particles = [];
          this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
        }
      }

      this.confetti = new Confetti(canvas);

      // 左侧发射
      this.confetti.fire({
        particleCount: 50,
        angle: 45, // 稍微加大仰角
        spread: 60,
        startVelocity: 60, // 速度翻倍
        x: 0,
        y: 0.5,
        gravity: 0.5, // 减小重力
      });
      // 右侧发射
      this.confetti.fire({
        particleCount: 50,
        angle: 135, // 稍微加大仰角
        spread: 60,
        startVelocity: 60, // 速度翻倍
        x: 1,
        y: 0.5,
        gravity: 0.5, // 减小重力
      });
    },
  },
};
</script>

<style lang="less" scoped>
.srtx_bg {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: #ffffff;
  opacity: 0.9;
  z-index: 999;
}
.srtx_imags {
  position: relative;
  top: 118px;
  left: 50%;
  transform: translateX(-50%);
  width: 317px;
  height: 398px;
  background: url("/src/assets/iconIndex/srtx_imags.png");
  background-size: 100% 100%;
}
.srtx_name {
  position: absolute;
  top: 58.5%;
  left: 50%;
  transform: translateX(-50%);
  font-size: 27px;
  font-family: HarmonyOS Sans-Bold, HarmonyOS Sans;
  font-weight: 700;
  color: #af6d2f;
  opacity: 0; /* 初始透明 */
  animation: floatIn 1.2s ease-out forwards;
  animation-delay: 0.5s; /* 等彩纸飞一会儿再出来 */
}

.srtx_nametwo {
  width: 100%;
  position: absolute;
  top: 72%;
  left: 50%;
  transform: translateX(-50%) translateY(30px); /* 初始下移一点 */
  font-size: 38px;
  font-family: HarmonyOS Sans-Bold, HarmonyOS Sans;
  font-weight: 700;
  color: #af6d2f;
  opacity: 0; /* 初始透明 */
  animation: floatIn 1.2s ease-out forwards;
  animation-delay: 0.2s; /* 比上面的文字早一点出现 */
}
/* 飘入动画 */
@keyframes floatIn {
  0% {
    opacity: 0;
    transform: translateX(-50%) translateY(30px) rotate(-5deg);
  }
  70% {
    opacity: 1;
    transform: translateX(-50%) translateY(-8px) rotate(3deg);
  }
  100% {
    opacity: 1;
    transform: translateX(-50%) translateY(0) rotate(0);
  }
}
.leift_lp {
  position: absolute;
  top: 509px;
  left: 0px;
  width: 84px;
  height: 99px;
  background: url("/src/assets/iconIndex/leift_lp.png");
  background-size: 100% 100%;
  transform: translateX(-100%); /* 初始完全隐藏在左侧 */
  transition: transform 0.4s ease-out;
  animation: slideInLeft 0.4s ease-out forwards;
}

.right_lp {
  position: absolute;
  top: 477px;
  right: 0;
  width: 78px;
  height: 77px;
  background: url("/src/assets/iconIndex/right_lp.png");
  background-size: 100% 100%;
  transform: translateX(100%); /* 初始完全隐藏在右侧 */
  transition: transform 0.4s ease-out;
  animation: slideInRight 0.4s ease-out forwards;
}

/* 左侧礼花筒动画：从左滑入一半 */
@keyframes slideInLeft {
  0% {
    transform: translateX(-100%);
  }
  100% {
    transform: translateX(-30%);
  } /* 只露出一半 */
}

/* 右侧礼花筒动画：从右滑入一半 */
@keyframes slideInRight {
  0% {
    transform: translateX(100%);
  }
  100% {
    transform: translateX(30%);
  } /* 只露出一半 */
}
.confetti-canvas {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  z-index: 9999;
}
</style>
